{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(f\"Type of 42 is {type(42)}\")\n",
    "print(f\"Type of 3.14 is {type(3.14)}\")\n",
    "print(f\"Type of 'hello' is {type('hello')}\")\n",
    "print(f\"Type of [1, 2, 3] is {type([1, 2, 3])}\")\n",
    "print(f\"Type of {{'key': 'value'}} is {type({'key': 'value'})}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyClass:\n",
    "    pass\n",
    "\n",
    "\n",
    "obj = MyClass()\n",
    "print(type(obj))  # Output: <class '__main__.MyClass'>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "42\n",
      "hello\n",
      "<class '__main__.DynamicClass'>\n"
     ]
    }
   ],
   "source": [
    "# Dynamically create a class\n",
    "DynamicClass = type(\n",
    "    \"DynamicClass\", (object,), {\"attr\": 42, \"method\": lambda self: \"hello\"}\n",
    ")\n",
    "\n",
    "# Create an instance of the dynamically created class\n",
    "instance = DynamicClass()\n",
    "print(instance.attr)  # Output: 42\n",
    "print(instance.method())  # Output: 'hello'\n",
    "print(type(instance))  # Output: <class '__main__.DynamicClass'>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "class Parent:\n",
    "    pass\n",
    "\n",
    "\n",
    "class Child(Parent):\n",
    "    pass\n",
    "\n",
    "\n",
    "obj = Child()\n",
    "\n",
    "print(type(obj) is Parent)  # Output: False (because it's specifically a Child)\n",
    "print(isinstance(obj, Parent))  # Output: True (Child is a subclass of Parent)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "len is of type <class 'builtin_function_or_method'>\n",
      "zip is of type <class 'type'>\n"
     ]
    }
   ],
   "source": [
    "print(f\"len is of type {type(len)}\")\n",
    "print(f\"zip is of type {type(zip)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "__class__ assignment only supported for mutable types or ModuleType subclasses",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[8], line 10\u001b[0m\n\u001b[1;32m      7\u001b[0m my_list \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m2\u001b[39m, \u001b[38;5;241m3\u001b[39m]\n\u001b[1;32m      9\u001b[0m \u001b[38;5;66;03m# Dynamically change the class of the list\u001b[39;00m\n\u001b[0;32m---> 10\u001b[0m \u001b[43mmy_list\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;18;43m__class__\u001b[39;49m \u001b[38;5;241m=\u001b[39m CustomList\n\u001b[1;32m     12\u001b[0m \u001b[38;5;66;03m# Now it behaves like an instance of CustomList\u001b[39;00m\n\u001b[1;32m     13\u001b[0m \u001b[38;5;28mprint\u001b[39m(my_list\u001b[38;5;241m.\u001b[39mcustom_method())  \u001b[38;5;66;03m# Output: I'm a custom list!\u001b[39;00m\n",
      "\u001b[0;31mTypeError\u001b[0m: __class__ assignment only supported for mutable types or ModuleType subclasses"
     ]
    }
   ],
   "source": [
    "class A:\n",
    "    def method(self):\n",
    "        return \"Class A\"\n",
    "\n",
    "\n",
    "class B:\n",
    "    def method(self):\n",
    "        return \"Class B\"\n",
    "\n",
    "\n",
    "obj = A()\n",
    "print(obj.method())  # Output: Class A\n",
    "\n",
    "# Dynamically reassign the class\n",
    "obj.__class__ = B\n",
    "print(obj.method())  # Output: Class B"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
